/*
 *
 * FileName: SCMConfiguration.java
 * Author:   wx:fdzhangc
 * Date:     2021/11/24 10:22
 * Description: //模块目的、功能描述
 * History: //修改记录
 * <author>      <time>      <version>    <desc>
 * 修改人姓名    修改时间    版本号       描述
 */
package com.zhangc.zcscm.client;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.zhangc.zcscm.util.HttpClient;
import com.zhangc.zcscm.util.MD5Utils;
import com.zhangc.zcscm.util.ParamUtil;
import com.zhangc.zcscm.util.ServerNameGetter;

/**
 * 功能描述:<br>
 *
 * @author wx:fdzhangc
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
public class SCMConfiguration {
    private static Logger logger = LoggerFactory.getLogger(SCMConfiguration.class);
    protected static String CONFIG_FILE = "/scm.properties";
    public static final String PATH_SEPARATOR = "/";
    public static ConcurrentHashMap<String, SCMConfiguration> configs = new ConcurrentHashMap();
    private SCMClient.Environment environment;
    private String appCode = "";
    private String secretKey = "";
    private String scmServer = "";
    private String zkServer = "";

    public static void setConfigFilePath(String path) {
        CONFIG_FILE = path;
    }

    public static SCMConfiguration getInstance() {
        return getInstance(CONFIG_FILE);
    }

    public static SCMConfiguration getInstance(String configFile) {
        if (configs.containsKey(configFile)) {
            return (SCMConfiguration) configs.get(configFile);
        } else {
            InputStream inputStream = SCMConfiguration.class.getResourceAsStream(configFile);
            if (inputStream == null) {
                inputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream(configFile);
                if (inputStream == null) {
                    throw new SCMException("Can not load file " + configFile);
                }
            }

            SCMConfiguration var5;
            try {
                Properties properties = new Properties();
                properties.load(inputStream);
                SCMConfiguration config = new SCMConfiguration(properties);
                SCMConfiguration existed = (SCMConfiguration) configs.putIfAbsent(configFile, config);
                if (existed != null) {
                    config = existed;
                }

                var5 = config;
            } catch (Exception var14) {
                throw new SCMException("load scm config error", var14);
            } finally {
                try {
                    inputStream.close();
                } catch (IOException var13) {
                    logger.error("close stream error", var13);
                }

            }

            return var5;
        }
    }

    private String getDC() {
        String value = System.getenv("ldc");
        if (StringUtils.isEmpty(value)) {
            value = System.getProperty("ldc");
            if (StringUtils.isEmpty(value)) {
                throw new RuntimeException("Can not find ldc in environment.");
            }
        }

        return value;
    }

    private SCMConfiguration(Properties properties) {
        this.appCode = (String) properties.get("appCode");
        this.secretKey = (String) properties.get("secretKey");
        this.scmServer = (String) properties.get("scmServer");
        String systemCode = (String) properties.get("systemCode");
        Properties localCached = new Properties();

        try {
            localCached = this.loadFromLocal();
        } catch (Exception var6) {
            logger.warn("Can not load properties from local file.", var6);
        }

        if (!"SCM".equals(systemCode)) {
            try {
                Map<String, Object> map = new HashMap();
                map.put("dc", this.getDC());
                this.zkServer = HttpClient.sendByPost(this.scmServer + "/zk.htm", ParamUtil.getEncodedParamFromMap(map), 30000, 3, 2000);
                localCached.put("zkServer", this.zkServer);
            } catch (Exception var8) {
                logger.error("Can not get zk list from " + this.scmServer, var8);
                this.zkServer = (String) localCached.get("zkServer");
                if (StringUtils.isEmpty(this.zkServer)) {
                    throw new SCMException("get zkServer error, please check scmServer in scm.properties is right to the environment!");
                }
            }

            try {
                String isPrd = HttpClient.sendByPost(this.scmServer + "/getEnv.htm", "", 30000, 3, 2000);
                this.environment = Boolean.valueOf(isPrd) ? SCMClient.Environment.PRD : SCMClient.Environment.NOT_PRD;
                localCached.put("scmEnv", this.environment.toString());
            } catch (Exception var7) {
                logger.error("Can not get environment from  " + this.scmServer, var7);
                Object env = localCached.get("scmEnv");
                if (null != env) {
                    this.environment = SCMClient.Environment.valueOf(env.toString());
                }

                if (null == this.environment) {
                    throw new SCMException("get environment error, please check scmServer in scm.properties is right to the environment!");
                }
            }

            if (StringUtils.isEmpty(this.secretKey) || StringUtils.isEmpty(this.appCode) || StringUtils.isEmpty(this.scmServer)) {
                throw new SCMException("Can not load scm.properties from local file, please check scm.properties location.");
            }
        } else {
            this.zkServer = (String) properties.get("zkServer");
            localCached.put("zkServer", this.zkServer);
        }

        this.saveToLocal(localCached);
    }

    private Properties loadFromLocal() throws Exception {
        String filePath = this.getLocalFilePath();
        File file = new File(filePath);
        if (!file.exists()) {
            return new Properties();
        } else {
            FileInputStream in = new FileInputStream(file);
            Properties properties = new Properties();

            try {
                properties.load(in);
            } finally {
                try {
                    in.close();
                } catch (IOException var11) {
                    logger.error("close stream error", var11);
                }

            }

            return properties;
        }
    }

    private String getLocalFilePath() {
        String filePath = ParamUtil.getCachePath();
        if (StringUtils.isEmpty(filePath)) {
            filePath = SCMConstant.FILE_PATH;
        }

        return filePath + "/" + SCMNodeImpl.StringFilter(MD5Utils.getMD5(this.scmServer + "_" + ServerNameGetter.getServerName()));
    }

    private void saveToLocal(Properties properties) {
        String filePath = this.getLocalFilePath();
        File file = new File(filePath);
        FileWriter fw = null;

        try {
            if (!file.exists()) {
                file.createNewFile();
            }

            fw = new FileWriter(file);
            properties.store(fw, "scm properties");
        } catch (IOException var14) {
            logger.error("Exception when save object to local.", var14);
        } finally {
            if (null != fw) {
                try {
                    fw.close();
                } catch (IOException var13) {
                    logger.error("close stream error", var13);
                }
            }

        }

    }

    public SCMClient.Environment getEnvironment() {
        return this.environment;
    }

    public String getAppCode() {
        return this.appCode;
    }

    public String getSecretKey() {
        return this.secretKey;
    }

    public String getScmServer() {
        return this.scmServer;
    }

    public String getZkServer() {
        return this.zkServer;
    }
}
